全部学科
Python全栈
python
NodeJS全栈
nodejs
📅 2026-05-21 5 分钟 ✍️ juanwangdev

GORM DeletedAt 字段使用

GORM 软删除机制通过 gorm.DeletedAt 字段实现逻辑删除,避免物理删除导致数据丢失。

软删除原理

工作方式

  • 调用 Delete 时自动将 deleted_at 字段设为当前时间
  • 查询时自动添加 WHERE deleted_at IS NULL 条件
  • 数据仍保留数据库中,可通过特殊查询恢复

基本使用

模型定义

Go
type User struct {
    gorm.Model        // 内置包含 DeletedAt 字段
    Name  string
    Email string
}

// 或手动定义
type Product struct {
    ID        uint
    Name      string
    DeletedAt gorm.DeletedAt `gorm:"index"`
}

执行软删除

Go
// 软删除单条记录
db.Delete(&user)

// 软删除多条记录
db.Delete(&users, []int{1, 2, 3})

// 根据条件软删除
db.Where("status = ?", "inactive").Delete(&User{})

生成的 SQL

SQL
UPDATE users SET deleted_at='2026-05-21 10:30:00' WHERE id = 1 AND deleted_at IS NULL

查询与恢复

查询已删除记录

Go
// 包含已删除记录
db.Unscoped().Find(&users)

// 仅查询已删除记录
db.Unscoped().Where("deleted_at IS NOT NULL").Find(&deletedUsers)

恢复数据

Go
// 恢复单条记录
db.Unscoped().Where("id = ?", 1).Update("deleted_at", nil)

// 批量恢复
db.Unscoped().Where("id IN ?", []int{1, 2, 3}).Update("deleted_at", nil)

软删除 vs 物理删除

操作方法SQL
软删除db.Delete()UPDATE SET deleted_at = NOW()
物理删除db.Unscoped().Delete()DELETE FROM table
软删除查询db.Where().Delete()UPDATE SET deleted_at = NOW()
物理删除查询db.Unscoped().Where().Delete()DELETE FROM table

注意事项

gorm.Model 已内置 DeletedAt 字段,嵌入即可启用软删除。

软删除的字段类型必须为 gorm.DeletedAt,而非普通 time.Time

唯一索引需考虑 deleted_at,避免软删除后冲突。

物理删除需显式调用 Unscoped(),防止误操作。

要点总结

  • 软删除通过 gorm.DeletedAt 字段实现,调用 Delete 自动设置删除时间
  • 查询默认过滤已删除记录,使用 Unscoped() 可查询已删除数据
  • 恢复数据需将 deleted_at 字段置为 nil
  • 软删除保留数据便于审计与恢复,但增加存储空间与查询复杂度
  • 物理删除需显式调用 Unscoped(),避免误删数据

存放路径:D:\git2\jwdev\articles\GORM\进阶\软删除机制\DeletedAt 字段使用.md

想在手机上练习这篇文章的配套题目?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一篇 GORM Jaeger 链路追踪插件
下一篇 → GORM 软删除查询过滤
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码